package com.tuling.tulingmallmygateway.filter;

import com.tuling.tulingmall.common.api.ResultCode;
import com.tuling.tulingmall.common.exception.GateWayException;
import com.tuling.tulingmallmygateway.propertites.NotAuthUrlPropertites;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.util.StringUtils;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.List;

@Component
@Order(0)
@EnableConfigurationProperties(value = NotAuthUrlPropertites.class)
public class MyAuthenticationFilter implements GlobalFilter {
    @Autowired
    private NotAuthUrlPropertites notAuthUrlPropertites;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //1.过滤不需要认证的url,比如/oauth/**
        String path = exchange.getRequest().getURI().getPath();
        
        if (shouldSkip(path)){
            //直接跳过
            chain.filter(exchange);
        }
        //2. 获取token
        // 从请求头中解析 Authorization  value:  bearer xxxxxxx
        // 或者从请求参数中解析 access_token
        //第一步:解析出我们Authorization的请求头  value为: “bearer XXXXXXXXXXXXXX”
        String authorization = exchange.getRequest().getHeaders().getFirst("Authorization");


        //第二步:判断Authorization的请求头是否为空
        if (StringUtils.isEmpty(authorization)){
            throw new GateWayException(ResultCode.AUTHORIZATION_HEADER_IS_EMPTY);
        }
        //3. 校验token
        // 拿到token后，通过公钥（需要从授权服务获取公钥）校验
        // 校验失败或超时抛出异常
        //第三步 校验我们的jwt 若jwt不对或者超时都会抛出异常


        //4. 校验通过后，从token中获取的用户登录信息存储到请求头中
        //第四步 把从jwt中解析出来的 用户登陆信息存储到请求头中



        return null;
    }

    private boolean shouldSkip(String path) {
        PathMatcher matcher = new AntPathMatcher();
        List<String> shouldSkipUrls = notAuthUrlPropertites.getShouldSkipUrls();
        boolean flag = shouldSkipUrls.stream().anyMatch(s -> {
             return matcher.match(s, path);
        });
        return flag;
    }
}
